package com.maozzi.service.es.impl;

import com.maozzi.api.es.EsService;
import com.maozzi.api.es.model.EsDTO;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * es DSL 语法，这里使用的是精确匹配，更多的写法自行百度
 *
 * @author maozi
 */
@Service
@Slf4j
public class EsServiceImpl implements EsService {
	@Value("${elasticsearch.index}")
	private String index;

	@Resource
	private RestHighLevelClient client;

	@Override
	public List<EsDTO> search(String keyword) {
		List<EsDTO> list = new ArrayList<>();
		try {
			// 这里es索引是可以传多个的
			SearchRequest request = new SearchRequest(index);
			SearchSourceBuilder builder = SearchSourceBuilder.searchSource()
					.query(QueryBuilders.matchAllQuery())
					.fetchSource(new String[]{}, new String[]{});
			// 精确匹配
			if (StringUtils.hasText(keyword)) {
				builder.query(QueryBuilders.termQuery("name", keyword));
			}
			request.source(builder);
			SearchResponse response = client.search(request, RequestOptions.DEFAULT);
			SearchHits hits = response.getHits();
			for (SearchHit hit : hits.getHits()) {
				String id = hit.getId();
				if ("%{id}".equals(id)) {
					continue;
				}
				Map<String, Object> map = hit.getSourceAsMap();
				String dtoId = String.valueOf(map.get("id"));
				String name = String.valueOf(map.get("name"));
				EsDTO dto = new EsDTO(dtoId, name);
				list.add(dto);
			}
		} catch (Exception e) {
			log.error("EsServiceImpl search => param[keyword]={}", keyword, e);
		}
		return list;
	}
}
